import { toast as showToast } from "@/BtComponents/BtToast/store"
import { useTokenStore } from '@/stores/useTokenStore';
import Taro from '@tarojs/taro'
import Schema from "async-validator"
import { IGetCommon } from '@/api/methods/common.type'
import { IUtils } from './interface'
/**
 * @description: page init 静默登录后执行业务逻辑
 * @return {*}
 */
const initPage = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      const token = useTokenStore.getState().token
      if (token) {
        resolve(token)
      } else {
        useTokenStore.subscribe(state => {
          if (state.token) {
            // 解决toke请求header没有携带上
            resolve(token)
          }
        })
      }
    }, 100)
  })
}

/**
 * @description: toast 消息
 * @param {string} text
 * @param {string} icon
 * @return {*}
 */
const toast = (text: string, icon?: string) => {
  showToast(text, icon)
}

/**
 * @description: 显示/隐藏loading
 * @param {boolean} show - 是否显示loading
 * @param {string} title - loading提示文字
 * @return {*}
 */
const loading = (show: boolean, title = '加载中...') => {
  if (show) {
    Taro.showLoading({
      title,
      mask: true
    })
  } else {
    Taro.hideLoading()
  }
}
const sessionCache = () => {
  // 内存存储 - 数据存储在小程序的运行内存中，小程序关闭后数据丢失
  const sessionStorage = {
    set(key: string, value: string) {
      if (key != null && value != null) {
        Taro.setStorage({ key, data: value })
      }
    },
    get(key: string) {
      if (key == null) {
        return null
      }
      return Taro.getStorage({
        key
      }).catch(() => null)
    },
    setJSON(key: string, jsonValue: Record<string, any>) {
      if (jsonValue != null) {
        this.set(key, JSON.stringify(jsonValue))
      }
    },
    async getJSON(key: string) {
      const value = await this.get(key)
      if (value != null) {
        return JSON.parse(value.data)
      }
    },
    remove(key: string) {
      Taro.removeStorage({ key })
    },
  }
  // 本地存储 - 数据存储在本地，即使小程序关闭后数据依然保留，直到手动清除
  const localStorage = {
    set(key: string, value: string) {
      if (key != null && value != null) {
        Taro.setStorageSync(key, value)
      }
    },
    get(key: string) {
      if (key == null) {
        return null
      }
      return Taro.getStorageSync(key)
    },
    setJSON(key: string, jsonValue: Record<string, any>) {
      if (jsonValue != null) {
        this.set(key, JSON.stringify(jsonValue))
      }
    },
    getJSON(key: string) {
      const value = this.get(key)
      if (value != null) {
        return JSON.parse(value)
      }
    },
    remove(key: string) {
      Taro.removeStorageSync(key)
    },
  }

  return {
    /**
     * 本地存储
     */
    session: sessionStorage,
    /**
     * 内存存储
     */
    local: localStorage,
  }
}

// 验证
/**
 * @description: 验证
 * @param {any} params
 * @param {any} rules
 * @return {*}
 */
const checkReg = (params: any, rules: any, showToast = true) => {
  const validator = new Schema(rules)

  return new Promise((resolve, reject) => {
    validator.validate(params, (errors) => {
      if (errors) {
        if (showToast) {
          Taro.showToast({
            title: errors[0].message || '请填写完整信息',
            icon: 'none'
          })
        }
        reject(errors[0].message)
      } else {
        resolve(true)
      }
    })
  })
}

// 登录校验+居民认证+是否首次进入
const isLoginAndResidentAuth = (userInfo: any | null, type: 'LOGIN' | 'RESIDENT', isload?:boolean) => {
  // 包含userInfo为unll/undefined，以及为一个空对象的情况
  console.log(Object.keys(userInfo).length === 0, 'userInfo')
  if ((!userInfo || Object.keys(userInfo).length === 0) && type === 'LOGIN') {
    return type
  }


  // 抽取居民认证状态
  if (type === 'RESIDENT') {

    const state = userInfo.meta?.RESIDENT?.state

    const passAt = userInfo.meta?.RESIDENT?.passAt
    if(!userInfo.meta?.RESIDENT){
      return 'ERROR'
    }
    if (userInfo.meta?.RESIDENT && !passAt) {
      if (state === 'REJECT') {
        return 'REJECT'
      } else if (state === 'PENDING' && !isload) {
        Taro.showToast({
          title: '居民认证审核中,请稍后再试',
          icon: 'none'
        })
        return 'PENDING'
      }
    }

  }

  return true
}

// 判断是否有底部安全区
const hasBottomSafeArea = () => {
  const sys = Taro.getSystemInfoSync()
  if (sys?.platform === 'ios' || sys?.platform === 'devtools') {
    return sys?.safeArea?.top && sys?.safeArea?.top > 20
  }
  return false
}


/**
 * @description: 判断操作权限
 * @param {PermissionItem[]} permissions - 权限列表
 * @param {PermissionCheck | PermissionCheck[]} check - 需要检查的权限
 * @return {boolean | boolean[]} - 返回单个boolean或boolean数组
 */
const hasOperatePermission = (permissions: IGetCommon.ResPermissionList[], check: IUtils.PermissionCheck | IUtils.PermissionCheck[]): boolean | boolean[] => {
  // 如果check是数组，返回多个boolean结果
  if (Array.isArray(check)) {
    return check.map(item => checkSinglePermission(permissions, item));
  }
  // 如果check是单个对象，返个boolean结果
  return checkSinglePermission(permissions, check);
}

/**
 * @description: 检查单个权限
 * @param {PermissionItem[]} permissions - 权限列表 module默认是NJG
 * @param {PermissionCheck} check - 需要检查的权限
 * @return {boolean} - 是否有权限
 */
const checkSinglePermission = (permissions: IGetCommon.ResPermissionList[], check: IUtils.PermissionCheck): boolean => {
  check.module = check.module || 'NJG'
  check.code = check.code || 'AUDIT'
  return permissions.some(item =>
    item.permission.module.module === check.module &&
    item.operation.entity.entity === check.entity &&
    item.operation.code === check.code
  );
}

/**
 * @description: 基于用户权限字符串判断是否有权限（用于mine页面等场景）
 * @param {string} rule - 权限规则字符串，如 'FRANCHISEE:CUSTOMER_ORDER:FINANCE_READ'
 * @param {number} userId - 用户ID，用于判断是否已登录
 * @return {boolean} - 是否有权限
 */
const hasPermissionByRule = (rule?: string): boolean => {
  // 无需权限直接通过
  if (!rule) {
    return true
  }
  const userId = Taro.getStorageSync('userId')
  // 未登录直接拒绝
  if (!userId) {
    return false
  }

  const userPermissions = Taro.getStorageSync('userPermissions') || []
  // 检查权限数组是否包含该规则
  return Array.isArray(userPermissions) && userPermissions.includes(rule)
}

export default {
  sessionCache,
  initPage,
  toast,
  loading,
  checkReg,
  // isResidentAuth,
  hasBottomSafeArea,
  hasOperatePermission,
  hasPermissionByRule,
  isLoginAndResidentAuth
}
